/*
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
*/

#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "trial_of_the_champion.h"
#include "Vehicle.h"
#include "Player.h"

const Position SpawnPosition = {746.67f, 684.08f, 412.5f, 4.65f};
#define CLEANUP_CHECK_INTERVAL	5000

class instance_trial_of_the_champion : public InstanceMapScript
{
public:
	instance_trial_of_the_champion() : InstanceMapScript("instance_trial_of_the_champion", 650) { }

	InstanceScript* GetInstanceScript(InstanceMap* pMap) const
	{
		return new instance_trial_of_the_champion_InstanceMapScript(pMap);
	}

	struct instance_trial_of_the_champion_InstanceMapScript : public InstanceScript
	{
		instance_trial_of_the_champion_InstanceMapScript(Map* pMap) : InstanceScript(pMap) { Initialize(); }

		bool CLEANED;
		TeamId TeamIdInInstance;
		uint32 InstanceProgress;
		uint32 m_auiEncounter[MAX_ENCOUNTER];
		std::string str_data;

		std::list<uint64> VehicleList;
		EventMap events;
		uint8 Counter;
		uint8 temp1, temp2;
		bool shortver;
		bool bAchievIveHadWorse;

		uint64 NPC_AnnouncerGUID;
		uint64 NPC_TirionGUID;
		uint64 NPC_GrandChampionGUID[3];
		uint64 NPC_GrandChampionMinionsGUID[3][3];
		uint64 NPC_ArgentChampionGUID;
		uint64 NPC_ArgentSoldierGUID[3][3];
		uint64 NPC_MemoryEntry;
		uint64 NPC_BlackKnightVehicleGUID;
		uint64 NPC_BlackKnightGUID;
		uint64 GO_MainGateGUID;

		void Initialize()
		{
			TeamIdInInstance = TEAM_NEUTRAL;
			InstanceProgress = 0;
			memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));

			VehicleList.clear();
			CLEANED = false;
			events.Reset();
			events.RescheduleEvent(EVENT_CHECK_PLAYERS, 0);
			Counter = 0;
			temp1 = 0;
			temp2 = 0;
			shortver = false;
			bAchievIveHadWorse = true;

			NPC_AnnouncerGUID = 0;
			NPC_TirionGUID = 0;
			memset(&NPC_GrandChampionGUID, 0, sizeof(NPC_GrandChampionGUID));
			memset(&NPC_GrandChampionMinionsGUID, 0, sizeof(NPC_GrandChampionMinionsGUID));
			memset(&NPC_ArgentSoldierGUID, 0, sizeof(NPC_ArgentSoldierGUID));
			NPC_ArgentChampionGUID = 0;
			NPC_MemoryEntry = 0;
			NPC_BlackKnightVehicleGUID = 0;
			NPC_BlackKnightGUID = 0;
			GO_MainGateGUID = 0;
		}

		bool IsEncounterInProgress() const
		{
			for( uint8 i = 0; i < MAX_ENCOUNTER; ++i )
				if( m_auiEncounter[i] == IN_PROGRESS )
					return true;

			return false;
		}

		void OnCreatureCreate(Creature* creature)
		{
			if (TeamIdInInstance == TEAM_NEUTRAL)
			{
				Map::PlayerList const &players = instance->GetPlayers();
				if( !players.isEmpty() )
					if( Player* pPlayer = players.begin()->GetSource() )
						TeamIdInInstance = pPlayer->GetTeamId();
			}

			switch( creature->GetEntry() )
			{
				// Grand Champions:
				case NPC_MOKRA:
					if( TeamIdInInstance == TEAM_HORDE )
						creature->UpdateEntry(NPC_JACOB);
					break;
				case NPC_ERESSEA:
					if( TeamIdInInstance == TEAM_HORDE )
						creature->UpdateEntry(NPC_AMBROSE);
					break;
				case NPC_RUNOK:
					if( TeamIdInInstance == TEAM_HORDE )
						creature->UpdateEntry(NPC_COLOSOS);
					break;
				case NPC_ZULTORE:
					if( TeamIdInInstance == TEAM_HORDE )
						creature->UpdateEntry(NPC_JAELYNE);
					break;
				case NPC_VISCERI:
					if( TeamIdInInstance == TEAM_HORDE )
						creature->UpdateEntry(NPC_LANA);
					break;

				// Grand Champion Minions:
				case NPC_ORGRIMMAR_MINION: 
					if( TeamIdInInstance == TEAM_HORDE )
						creature->UpdateEntry(NPC_STORMWIND_MINION);
					break;
				case NPC_SILVERMOON_MINION: 
					if( TeamIdInInstance == TEAM_HORDE )
						creature->UpdateEntry(NPC_GNOMEREGAN_MINION);
					break;
				case NPC_THUNDER_BLUFF_MINION: 
					if( TeamIdInInstance == TEAM_HORDE )
						creature->UpdateEntry(NPC_EXODAR_MINION);
					break;
				case NPC_SENJIN_MINION: 
					if( TeamIdInInstance == TEAM_HORDE )
						creature->UpdateEntry(NPC_DARNASSUS_MINION);
					break;
				case NPC_UNDERCITY_MINION: 
					if( TeamIdInInstance == TEAM_HORDE )
						creature->UpdateEntry(NPC_IRONFORGE_MINION);
					break;

				// Argent Champion:
				case NPC_EADRIC:
				case NPC_PALETRESS:
					NPC_ArgentChampionGUID = creature->GetGUID();
					break;

				// Coliseum Announcer:
				case NPC_JAEREN:
					NPC_AnnouncerGUID = creature->GetGUID();
					//if( TeamIdInInstance == TEAM_ALLIANCE )
					//	creature->UpdateEntry(NPC_ARELAS);
					creature->SetReactState(REACT_PASSIVE);
					break;

				// Highlord Tirion Fordring
				case NPC_TIRION:
					NPC_TirionGUID = creature->GetGUID();
					break;

				// Beginning vehicles:
				case VEHICLE_ARGENT_WARHORSE:
				case VEHICLE_ARGENT_BATTLEWORG:
					if( InstanceProgress < INSTANCE_PROGRESS_CHAMPIONS_UNMOUNTED && m_auiEncounter[0] == NOT_STARTED )
					{
						creature->DespawnOrUnsummon();
						creature->SetRespawnTime(3);
						VehicleList.push_back(creature->GetGUID());
					}
					else
						creature->DespawnOrUnsummon();
					break;
			}
			if (creature->GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID))
				if (const CreatureAddon* ca = creature->GetCreatureAddon())
					if (ca->mount != creature->GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID))
						creature->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, ca->mount);
		}

		void OnGameObjectCreate(GameObject* go)
		{
			switch( go->GetEntry() )
			{
				case GO_MAIN_GATE:
					GO_MainGateGUID = go->GetGUID();
					HandleGameObject(GO_MainGateGUID, false, go);
					break;
				case GO_SOUTH_PORTCULLIS:
				case GO_EAST_PORTCULLIS:
					HandleGameObject(go->GetGUID(), false, go);
					break;
			}
		}

		std::string GetSaveData()
		{
			OUT_SAVE_INST_DATA;
			std::ostringstream saveStream;
			saveStream << "T C " << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' << m_auiEncounter[2] << ' ' << InstanceProgress;
			str_data = saveStream.str();
			OUT_SAVE_INST_DATA_COMPLETE;
			return str_data;
		}

		void Load(const char* in)
		{
			CLEANED = false;
			events.Reset();
			events.RescheduleEvent(EVENT_CHECK_PLAYERS, 0);

			if( !in )
			{
				OUT_LOAD_INST_DATA_FAIL;
				return;
			}

			OUT_LOAD_INST_DATA(in);

			char dataHead1, dataHead2;
			uint16 data0, data1, data2, data3;
			std::istringstream loadStream(in);
			loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3;

			if( dataHead1 == 'T' && dataHead2 == 'C' )
			{
				m_auiEncounter[0] = data0;
				m_auiEncounter[1] = data1;
				m_auiEncounter[2] = data2;
				InstanceProgress = data3;
				if( InstanceProgress == INSTANCE_PROGRESS_CHAMPIONS_UNMOUNTED )
					InstanceProgress = INSTANCE_PROGRESS_INITIAL;

				for( uint8 i = 0; i < MAX_ENCOUNTER; ++i )
					if( m_auiEncounter[i] == IN_PROGRESS )
						m_auiEncounter[i] = NOT_STARTED;

			}
			else
				OUT_LOAD_INST_DATA_FAIL;

			OUT_LOAD_INST_DATA_COMPLETE;
		}

		// EVENT STUFF BELOW:

		void OnPlayerEnter(Player *)
		{
			if( DoNeedCleanup(true) )
				InstanceCleanup();

			events.RescheduleEvent(EVENT_CHECK_PLAYERS, CLEANUP_CHECK_INTERVAL);
		}

		bool DoNeedCleanup(bool /*enter*/)
		{
			uint8 aliveCount = 0;
			Map::PlayerList const &pl = instance->GetPlayers();
			for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
				if( Player* plr = itr->GetSource() )
					if( plr->IsAlive() && !plr->IsGameMaster() )
						++aliveCount;

			bool need = aliveCount==0;
			if( !need && CLEANED )
				CLEANED = false;
			return need;
		}

		void InstanceCleanup()
		{
			if( CLEANED )
				return;

			switch( InstanceProgress )
			{
				case INSTANCE_PROGRESS_INITIAL:
				case INSTANCE_PROGRESS_GRAND_CHAMPIONS_REACHED_DEST:
				case INSTANCE_PROGRESS_CHAMPION_GROUP_DIED_1:
				case INSTANCE_PROGRESS_CHAMPION_GROUP_DIED_2:
				case INSTANCE_PROGRESS_CHAMPION_GROUP_DIED_3:
					// revert to INSTANCE_PROGRESS_INITIAL
					{
						for( std::list<uint64>::const_iterator itr = VehicleList.begin(); itr != VehicleList.end(); ++itr )
							if( Creature* veh = instance->GetCreature(*itr) )
							{
								veh->DespawnOrUnsummon();
								veh->SetRespawnTime(3);
							}
						for( uint8 i=0; i<3; ++i )
						{
							for( uint8 j=0; j<3; ++j )
							{
								if( Creature* c = instance->GetCreature(NPC_GrandChampionMinionsGUID[i][j]) )
									c->DespawnOrUnsummon();
								NPC_GrandChampionMinionsGUID[i][j] = 0;
							}
							if( Creature* c = instance->GetCreature(NPC_GrandChampionGUID[i]) )
								c->DespawnOrUnsummon();
							NPC_GrandChampionGUID[i] = 0;
						}
						if( Creature* c = instance->GetCreature(NPC_AnnouncerGUID) )
						{
							c->DespawnOrUnsummon();
							c->SetHomePosition(748.309f, 619.488f, 411.172f, 4.71239f);
							c->SetPosition(748.309f, 619.488f, 411.172f, 4.71239f);
							c->SetRespawnTime(3);
							c->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
						}
						InstanceProgress = INSTANCE_PROGRESS_INITIAL;
					}
					break;
				case INSTANCE_PROGRESS_CHAMPIONS_UNMOUNTED:
					{
						if( Creature* announcer = instance->GetCreature(NPC_AnnouncerGUID) )
						{
							announcer->DespawnOrUnsummon();
							announcer->SetHomePosition(735.81f, 661.92f, 412.39f, 4.714f);
							announcer->SetPosition(735.81f, 661.92f, 412.39f, 4.714f);
							announcer->SetRespawnTime(3);
							announcer->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);

							for( uint8 i=0; i<3; ++i )
								if( Creature* c = instance->GetCreature(NPC_GrandChampionGUID[i]) )
								{
									uint32 entry = c->GetEntry();
									c->DespawnOrUnsummon();
									switch( i )
									{
										case 0:
											if( Creature* pBoss = announcer->SummonCreature(entry, 736.695f, 650.02f, 412.4f, 3*M_PI/2) )
											{
												NPC_GrandChampionGUID[0] = pBoss->GetGUID();
												pBoss->AI()->SetData(0, 2);
											}
											break;
										case 1:
											if( Creature* pBoss = announcer->SummonCreature(entry, 756.32f, 650.05f, 412.4f, 3*M_PI/2) )
											{
												NPC_GrandChampionGUID[1] = pBoss->GetGUID();
												pBoss->AI()->SetData(1, 2);
											}
											break;
										case 2:
											if( Creature* pBoss = announcer->SummonCreature(entry, 746.5f, 650.65f, 411.7f, 3*M_PI/2) )
											{
												NPC_GrandChampionGUID[2] = pBoss->GetGUID();
												pBoss->AI()->SetData(2, 2);
											}
											break;
									}
								}
						}
					}
					break;
				case INSTANCE_PROGRESS_CHAMPIONS_DEAD:
				case INSTANCE_PROGRESS_ARGENT_SOLDIERS_DIED:
					// revert to INSTANCE_PROGRESS_CHAMPIONS_DEAD
					{
						for( uint8 i=0; i<3; ++i )
							for( uint8 j=0; j<3; ++j )
							{
								if( Creature* c = instance->GetCreature(NPC_ArgentSoldierGUID[i][j]) )
									c->DespawnOrUnsummon();
								NPC_ArgentSoldierGUID[i][j] = 0;
							}
						if( Creature* c = instance->GetCreature(NPC_ArgentChampionGUID) )
						{
							c->AI()->DoAction(-1); // paletress despawn memory
							c->DespawnOrUnsummon();
						}
						NPC_ArgentChampionGUID = 0;
						if( Creature* c = instance->GetCreature(NPC_AnnouncerGUID) )
						{
							c->DespawnOrUnsummon();
							c->SetHomePosition(743.14f, 628.77f, 411.2f, 4.71239f);
							c->SetPosition(743.14f, 628.77f, 411.2f, 4.71239f);
							c->SetRespawnTime(3);
							c->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
						}
						NPC_MemoryEntry = 0;
						InstanceProgress = INSTANCE_PROGRESS_CHAMPIONS_DEAD;
					}
					break;
				case INSTANCE_PROGRESS_ARGENT_CHALLENGE_DIED:
					// revert to INSTANCE_PROGRESS_ARGENT_CHALLENGE_DIED
					{
						if( Creature* c = instance->GetCreature(NPC_BlackKnightVehicleGUID) )
							c->DespawnOrUnsummon();
						NPC_BlackKnightVehicleGUID = 0;
						if( Creature* c = instance->GetCreature(NPC_BlackKnightGUID) )
						{
							c->AI()->DoAction(-1);
							c->DespawnOrUnsummon();
						}
						NPC_BlackKnightGUID = 0;
						if( Creature* c = instance->GetCreature(NPC_AnnouncerGUID) )
						{
							c->DespawnOrUnsummon();
							c->SetHomePosition(743.14f, 628.77f, 411.2f, 4.71239f);
							c->SetPosition(743.14f, 628.77f, 411.2f, 4.71239f);
							c->SetRespawnTime(3);
							c->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
						}
						InstanceProgress = INSTANCE_PROGRESS_ARGENT_CHALLENGE_DIED;
					}
					break;
				case INSTANCE_PROGRESS_FINISHED:
					if( Creature* c = instance->GetCreature(NPC_AnnouncerGUID) )
						c->DespawnOrUnsummon();
					break;
			}

			HandleGameObject(GO_MainGateGUID, false);
			Counter = 0;
			SaveToDB();
			events.Reset();
			events.RescheduleEvent(EVENT_CHECK_PLAYERS, CLEANUP_CHECK_INTERVAL);

			CLEANED = true;
		}

		uint32 GetData(uint32 uiData) const
		{
			switch( uiData )
			{
				case DATA_INSTANCE_PROGRESS:
					return InstanceProgress;
				case DATA_TEAMID_IN_INSTANCE:
					return TeamIdInInstance;
			}

			return 0;
		}

		uint64 GetData64(uint32 uiData) const
		{
			switch( uiData )
			{
				case DATA_ANNOUNCER:
					return NPC_AnnouncerGUID;
				case DATA_PALETRESS:
					return NPC_ArgentChampionGUID;
			}

			return 0;
		}

		void SetData(uint32 uiType, uint32 uiData)
		{
			switch( uiType )
			{
				case DATA_ANNOUNCER_GOSSIP_SELECT:
					switch( InstanceProgress )
					{
						case INSTANCE_PROGRESS_INITIAL:
							if (uiData == 0) // normal intro
							{
								shortver = false;

								if( Creature* announcer = instance->GetCreature(NPC_AnnouncerGUID) )
								{
									if( GameObject* gate = instance->GetGameObject(GO_MainGateGUID) )
										announcer->SetFacingToObject(gate);
									if( Creature* tirion = instance->GetCreature(NPC_TirionGUID) )
										tirion->AI()->Talk(TEXT_WELCOME);
								}
								events.RescheduleEvent(EVENT_YELL_WELCOME_2, 8000);
							}
							else // short version
							{
								shortver = true;

								temp1 = urand(0,4);
								DoSummonGrandChampion(temp1, 0);
								do { temp2 = urand(0,4); } while( temp1 == temp2 );
								DoSummonGrandChampion(temp2, 1);
								uint8 number = 0;
								do { number = urand(0,4); } while( number == temp1 || number == temp2 );
								DoSummonGrandChampion(number, 2);

								InstanceProgress = INSTANCE_PROGRESS_GRAND_CHAMPIONS_REACHED_DEST;
								uiData = DONE; // save to db
								if( Creature* announcer = instance->GetCreature(NPC_AnnouncerGUID) )
								{
									announcer->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
									announcer->GetMotionMaster()->MovePoint(1, 735.81f, 661.92f, 412.39f);
								}
								events.ScheduleEvent(EVENT_GRAND_GROUP_1_MOVE_MIDDLE, 10000);
							}
							break;
						case INSTANCE_PROGRESS_CHAMPIONS_DEAD:
							if( Creature* announcer = instance->GetCreature(NPC_AnnouncerGUID) )
							{
								Counter = urand(0,1);
								if( Counter )
									announcer->AI()->Talk(TEXT_INTRODUCE_EADRIC);
								else
									announcer->AI()->Talk(TEXT_INTRODUCE_PALETRESS);
							}
							events.RescheduleEvent(EVENT_START_ARGENT_CHALLENGE_INTRO, 0);
							break;
						case INSTANCE_PROGRESS_ARGENT_CHALLENGE_DIED:
							if( Creature* tirion = instance->GetCreature(NPC_TirionGUID) )
								tirion->AI()->Talk(TEXT_BK_INTRO);
							events.RescheduleEvent(EVENT_SUMMON_BLACK_KNIGHT, 3000);
							break;
					}
					break;
				case DATA_GRAND_CHAMPION_REACHED_DEST:
					if (shortver)
						break;
					switch( uiData )
					{
						case 0:
							events.ScheduleEvent(EVENT_SUMMON_GRAND_CHAMPION_2, 0);
							break;
						case 1:
							events.ScheduleEvent(EVENT_SUMMON_GRAND_CHAMPION_3, 0);
							break;
						case 2:
							if( Creature* announcer = instance->GetCreature(NPC_AnnouncerGUID) )
							{
								InstanceProgress = INSTANCE_PROGRESS_GRAND_CHAMPIONS_REACHED_DEST;
								uiData = DONE; // save to db
								announcer->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
								announcer->GetMotionMaster()->MovePoint(1, 735.81f, 661.92f, 412.39f);
								events.ScheduleEvent(EVENT_GRAND_GROUP_1_MOVE_MIDDLE, 8500);
							}
							break;
					}
					break;
				case DATA_MOUNT_DIED:
					switch( InstanceProgress )
					{
						case INSTANCE_PROGRESS_GRAND_CHAMPIONS_REACHED_DEST: // fighting group 1/3
							if( ++Counter >= 3 )
							{
								Counter = 0;
								InstanceProgress = INSTANCE_PROGRESS_CHAMPION_GROUP_DIED_1;
								uiData = DONE; // save to db
								events.ScheduleEvent(EVENT_GRAND_GROUP_2_MOVE_MIDDLE, 0);
							}
							break;
						case INSTANCE_PROGRESS_CHAMPION_GROUP_DIED_1: // fighting group 2/3
							if( ++Counter >= 3 )
							{
								Counter = 0;
								InstanceProgress = INSTANCE_PROGRESS_CHAMPION_GROUP_DIED_2;
								uiData = DONE; // save to db
								events.ScheduleEvent(EVENT_GRAND_GROUP_3_MOVE_MIDDLE, 0);
							}
							break;
						case INSTANCE_PROGRESS_CHAMPION_GROUP_DIED_2: // fighting group 3/3
							if( ++Counter >= 3 )
							{
								Counter = 0;
								InstanceProgress = INSTANCE_PROGRESS_CHAMPION_GROUP_DIED_3;
								uiData = DONE; // save to db
								events.ScheduleEvent(EVENT_GRAND_CHAMPIONS_MOVE_MIDDLE, 0);
							}
							break;
						case INSTANCE_PROGRESS_CHAMPION_GROUP_DIED_3: // fighting grand champions (on vehicles)
							if( ++Counter >= 3 )
							{
								Counter = 0;
								InstanceProgress = INSTANCE_PROGRESS_CHAMPIONS_UNMOUNTED;
								for( std::list<uint64>::const_iterator itr = VehicleList.begin(); itr != VehicleList.end(); ++itr )
									if( Creature* veh = instance->GetCreature(*itr) )
										veh->DespawnOrUnsummon();
								events.ScheduleEvent(EVENT_GRAND_CHAMPIONS_MOVE_SIDE, 0);
							}
							break;
					}
					break;
				case DATA_REACHED_NEW_MOUNT:
					--Counter;
					break;
				case DATA_GRAND_CHAMPION_DIED:
					if( ++Counter >= 3 )
					{
						Counter = 0;
						VehicleList.clear();
						uiData = DONE;
						InstanceProgress = INSTANCE_PROGRESS_CHAMPIONS_DEAD;
						m_auiEncounter[0] = DONE;
						bool creditCasted = false;
						for( uint8 i=0; i<3; ++i )
							if( Creature* c = instance->GetCreature(NPC_GrandChampionGUID[i]) )
							{
								c->GetMotionMaster()->MovePoint(9, 747.36f, 670.07f, 411.9f);
								if (!creditCasted)
								{
									c->CastSpell((Unit*)NULL, 68572, true);
									creditCasted = true;
								}
							}
						if( Creature* announcer = instance->GetCreature(NPC_AnnouncerGUID) )
						{
							announcer->GetMotionMaster()->MovePoint(0, 743.14f, 628.77f, 411.2f);
							announcer->SummonGameObject(instance->IsHeroic() ? GO_CHAMPIONS_LOOT_H : GO_CHAMPIONS_LOOT, 746.59f, 618.49f, 411.09f, 1.42f, 0, 0, 0, 0, 90000000); // [LOOT]
							events.ScheduleEvent(EVENT_RESTORE_ANNOUNCER_GOSSIP, 15000);
							events.ScheduleEvent(EVENT_GRATZ_SLAIN_CHAMPIONS, 6000);
						}

						// bind players to instance
						if( instance->IsHeroic() )
							instance->ToInstanceMap()->PermBindAllPlayers();
					}
					break;
				case DATA_ARGENT_SOLDIER_DEFEATED:
					if( ++Counter >= 9 )
					{
						Counter = 0;
						InstanceProgress = INSTANCE_PROGRESS_ARGENT_SOLDIERS_DIED;
						uiData = DONE; // save to db
						events.ScheduleEvent(EVENT_ARGENT_CHALLENGE_MOVE_FORWARD, 0);
					}
					break;
				case BOSS_ARGENT_CHALLENGE:
					{
						m_auiEncounter[1] = uiData;
						if( uiData == DONE )
						{
							InstanceProgress = INSTANCE_PROGRESS_ARGENT_CHALLENGE_DIED;
							events.ScheduleEvent(EVENT_ARGENT_CHALLENGE_RUN_MIDDLE, 0);
						}
					}
					break;
				case DATA_MEMORY_ENTRY:
					NPC_MemoryEntry = uiData;
					break;
				case DATA_SKELETAL_GRYPHON_LANDED:
					{
						events.ScheduleEvent(EVENT_START_BLACK_KNIGHT_SCENE, 3000);
					}
					break;
				case BOSS_BLACK_KNIGHT:
					{
						m_auiEncounter[2] = uiData;
						if (uiData == NOT_STARTED)
							bAchievIveHadWorse = true;
						else if( uiData == DONE )
							InstanceProgress = INSTANCE_PROGRESS_FINISHED;
					}
					break;
				case DATA_ACHIEV_IVE_HAD_WORSE:
					if (bAchievIveHadWorse)
						bAchievIveHadWorse = false;
					break;
			}

			if( uiData == DONE )
				SaveToDB();
		}

		void DoSummonGrandChampion(uint32 BossNumber, uint8 BossOrder)
		{
			uint32 CHAMPION_TO_SUMMON = 0;
			uint32 MINION_TO_SUMMON = 0;
			int32 TEXT_ID = 0;

			switch( BossNumber )
			{
				case 0:
					CHAMPION_TO_SUMMON = NPC_MOKRA;
					MINION_TO_SUMMON = NPC_ORGRIMMAR_MINION;
					TEXT_ID = TEXT_MOKRA_SKILLCRUSHER;
					break;
				case 1:
					CHAMPION_TO_SUMMON = NPC_ERESSEA;
					MINION_TO_SUMMON = NPC_SILVERMOON_MINION;
					TEXT_ID = TEXT_ERESSEA_DAWNSINGER;
					break;
				case 2:
					CHAMPION_TO_SUMMON = NPC_RUNOK;
					MINION_TO_SUMMON = NPC_THUNDER_BLUFF_MINION;
					TEXT_ID = TEXT_RUNOK_WILDMANE;
					break;
				case 3:
					CHAMPION_TO_SUMMON = NPC_ZULTORE;
					MINION_TO_SUMMON = NPC_SENJIN_MINION;
					TEXT_ID = TEXT_ZUL_TORE;
					break;
				case 4:
					CHAMPION_TO_SUMMON = NPC_VISCERI;
					MINION_TO_SUMMON = NPC_UNDERCITY_MINION;
					TEXT_ID = TEXT_DEATHSTALKER_VESCERI;
					break;
				default:
					return;
			}

			Position SpawnPos = SpawnPosition;
			if (shortver)
				switch (BossOrder)
				{
					case 0:
						SpawnPos.Relocate(780.43f, 607.15f, 411.82f);
						break;
					case 1:
						SpawnPos.Relocate(768.72f, 581.01f, 411.92f);
						break;
					case 2:
						SpawnPos.Relocate(784.02f, 645.33f, 412.39f);
						break;
				}

			if( Creature* pBoss = instance->SummonCreature(CHAMPION_TO_SUMMON, SpawnPos) )
			{
				NPC_GrandChampionGUID[BossOrder] = pBoss->GetGUID();
				pBoss->ToCreature()->SetHomePosition(748.309f, 619.448f, 411.3f, M_PI/2);
				pBoss->ToCreature()->SetReactState(REACT_PASSIVE);
				pBoss->AI()->SetData(BossOrder, (shortver ? 1 : 0));

				for( uint8 i = 0; i < 3; ++i )
					if( Creature* pAdd = instance->SummonCreature(MINION_TO_SUMMON, SpawnPos) )
					{
						NPC_GrandChampionMinionsGUID[BossOrder][i] = pAdd->GetGUID();
						pAdd->SetHomePosition(748.309f, 619.448f, 411.3f, M_PI/2);
						pAdd->GetMotionMaster()->MoveFollow(pBoss, 2.0f, (i+1)*M_PI/2);
						pAdd->SetReactState(REACT_PASSIVE);
					}

			}
			
			if (!shortver)
				if( Creature* announcer = instance->GetCreature(NPC_AnnouncerGUID) )
				{
					if( TeamIdInInstance == TEAM_HORDE )
						TEXT_ID -= 10;
					announcer->AI()->Talk(TEXT_ID);
					announcer->AI()->Talk(TEXT_ID+1);
				}
		}

		void Update(uint32 diff)
		{
			events.Update(diff);
			switch( events.GetEvent() )
			{
				case EVENT_NULL:
					break;
				case EVENT_CHECK_PLAYERS:
					{
						if( DoNeedCleanup(false) )
							InstanceCleanup();
						events.RepeatEvent(CLEANUP_CHECK_INTERVAL);
					}
					break;
				case EVENT_SUMMON_GRAND_CHAMPION_1:
					{
						temp1 = urand(0,4);
						DoSummonGrandChampion(temp1, 0);
						HandleGameObject(GO_MainGateGUID, true);
						events.ScheduleEvent(EVENT_CLOSE_GATE, 6000);
						events.PopEvent();
					}
					break;
				case EVENT_SUMMON_GRAND_CHAMPION_2:
					{
						do { temp2 = urand(0,4); } while( temp1 == temp2 );
						DoSummonGrandChampion(temp2, 1);
						HandleGameObject(GO_MainGateGUID, true);
						events.ScheduleEvent(EVENT_CLOSE_GATE, 6000);
						events.PopEvent();
					}
					break;
				case EVENT_SUMMON_GRAND_CHAMPION_3:
					{
						uint8 number = 0;
						do { number = urand(0,4); } while( number == temp1 || number == temp2 );
						DoSummonGrandChampion(number, 2);
						HandleGameObject(GO_MainGateGUID, true);
						events.ScheduleEvent(EVENT_CLOSE_GATE, 6000);
						events.PopEvent();
					}
					break;
				case EVENT_CLOSE_GATE:
					{
						HandleGameObject(GO_MainGateGUID, false);
						events.PopEvent();
					}
					break;
				case EVENT_YELL_WELCOME_2:
					{
						if( Creature* tirion = instance->GetCreature(NPC_TirionGUID) )
							tirion->AI()->Talk(TEXT_WELCOME_2);
						events.RescheduleEvent(EVENT_SUMMON_GRAND_CHAMPION_1, 8000);
						events.PopEvent();
					}
					break;
				case EVENT_GRAND_GROUP_1_MOVE_MIDDLE:
					{
						if( Creature* announcer = instance->GetCreature(NPC_AnnouncerGUID) )
						{
							announcer->SetFacingTo(4.714f);
							if( Creature* tirion = instance->GetCreature(NPC_TirionGUID) )
								tirion->AI()->Talk(TEXT_BEGIN);
						}
						for( uint8 i=0; i<3; ++i )
							if( Creature* c = instance->GetCreature(NPC_GrandChampionMinionsGUID[1][i]) )
							{
								float angle = rand_norm()*2*M_PI;
								c->GetMotionMaster()->MovePoint(0, 748.309f+3.0f*cos(angle), 619.448f+3.0f*sin(angle), 411.3f);
							}

						events.ScheduleEvent(EVENT_GRAND_GROUP_1_ATTACK, 3000);
						events.PopEvent();
					}
					break;
				case EVENT_GRAND_GROUP_1_ATTACK:
					{
						for( uint8 i=0; i<3; ++i )
							if( Creature* c = instance->GetCreature(NPC_GrandChampionMinionsGUID[1][i]) )
							{
								c->SetReactState(REACT_AGGRESSIVE);
								c->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
								if( Unit* target = c->SelectNearestTarget(200.0f) )
									c->AI()->AttackStart(target);
								c->AI()->DoZoneInCombat();
							}
						Counter = 0;
						events.PopEvent();
					}
					break;
				case EVENT_GRAND_GROUP_2_MOVE_MIDDLE:
					{
						for( uint8 i=0; i<3; ++i )
							if( Creature* c = instance->GetCreature(NPC_GrandChampionMinionsGUID[0][i]) )
							{
								float angle = rand_norm()*2*M_PI;
								c->GetMotionMaster()->MovePoint(0, 748.309f+3.0f*cos(angle), 619.448f+3.0f*sin(angle), 411.3f);
							}

						events.ScheduleEvent(EVENT_GRAND_GROUP_2_ATTACK, 3000);
						events.PopEvent();
					}
					break;
				case EVENT_GRAND_GROUP_2_ATTACK:
					{
						for( uint8 i=0; i<3; ++i )
							if( Creature* c = instance->GetCreature(NPC_GrandChampionMinionsGUID[0][i]) )
							{
								c->SetReactState(REACT_AGGRESSIVE);
								c->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
								if( Unit* target = c->SelectNearestTarget(200.0f) )
									c->AI()->AttackStart(target);
								c->AI()->DoZoneInCombat();
							}
						events.PopEvent();
					}
					break;
				case EVENT_GRAND_GROUP_3_MOVE_MIDDLE:
					{
						for( uint8 i=0; i<3; ++i )
							if( Creature* c = instance->GetCreature(NPC_GrandChampionMinionsGUID[2][i]) )
							{
								float angle = rand_norm()*2*M_PI;
								c->GetMotionMaster()->MovePoint(0, 748.309f+3.0f*cos(angle), 619.448f+3.0f*sin(angle), 411.3f);
							}

						events.ScheduleEvent(EVENT_GRAND_GROUP_3_ATTACK, 3000);
						events.PopEvent();
					}
					break;
				case EVENT_GRAND_GROUP_3_ATTACK:
					{
						for( uint8 i=0; i<3; ++i )
							if( Creature* c = instance->GetCreature(NPC_GrandChampionMinionsGUID[2][i]) )
							{
								c->SetReactState(REACT_AGGRESSIVE);
								c->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
								if( Unit* target = c->SelectNearestTarget(200.0f) )
									c->AI()->AttackStart(target);
								c->AI()->DoZoneInCombat();
							}
						events.PopEvent();
					}
					break;
				case EVENT_GRAND_CHAMPIONS_MOVE_MIDDLE:
					{
						for( uint8 i=0; i<3; ++i )
							if( Creature* c = instance->GetCreature(NPC_GrandChampionGUID[i]) )
							{
								float angle = rand_norm()*2*M_PI;
								c->GetMotionMaster()->MovePoint(4, 748.309f+3.0f*cos(angle), 619.448f+3.0f*sin(angle), 411.3f);
							}

						events.ScheduleEvent(EVENT_GRAND_CHAMPIONS_MOUNTS_ATTACK, 3000);
						events.PopEvent();
					}
					break;
				case EVENT_GRAND_CHAMPIONS_MOUNTS_ATTACK:
					{
						for( uint8 i=0; i<3; ++i )
							if( Creature* c = instance->GetCreature(NPC_GrandChampionGUID[i]) )
							{
								c->SetReactState(REACT_AGGRESSIVE);
								c->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
								if( Unit* target = c->SelectNearestTarget(200.0f) )
									c->AI()->AttackStart(target);
								c->AI()->DoZoneInCombat();
								c->CastSpell(c, 67865, true); // SPELL_TRAMPLE_AURA
							}
						events.PopEvent();
					}
					break;
				case EVENT_GRAND_CHAMPIONS_MOVE_SIDE:
					{
						for( uint8 i=0; i<3; ++i )
							if( Creature* c = instance->GetCreature(NPC_GrandChampionGUID[i]) )
							{
								c->AI()->DoAction(1);
								switch( i )
								{
									case 0:
										c->GetMotionMaster()->MovePoint(5, 736.695f, 650.02f, 412.4f);
										break;
									case 1:
										c->GetMotionMaster()->MovePoint(5, 756.32f, 650.05f, 412.4f);
										break;
									case 2:
										c->GetMotionMaster()->MovePoint(5, 746.5f, 650.65f, 411.7f);
										break;
								}
							}

						events.ScheduleEvent(EVENT_GRAND_CHAMPIONS_ATTACK, 15000);
						events.PopEvent();
					}
					break;
				case EVENT_GRAND_CHAMPIONS_ATTACK:
					{
						for( uint8 i=0; i<3; ++i )
							if( Creature* c = instance->GetCreature(NPC_GrandChampionGUID[i]) )
							{
								c->SetReactState(REACT_AGGRESSIVE);
								c->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
								if( Unit* target = c->SelectNearestTarget(200.0f) )
									c->AI()->AttackStart(target);
								c->AI()->DoZoneInCombat();
								c->AI()->DoAction(2);
							}
						events.PopEvent();
					}
					break;
				case EVENT_GRATZ_SLAIN_CHAMPIONS:
					{
						if( Creature* tirion = instance->GetCreature(NPC_TirionGUID) )
							tirion->AI()->Talk(TEXT_GRATZ_SLAIN_CHAMPIONS);
						events.PopEvent();
					}
					break;
				case EVENT_RESTORE_ANNOUNCER_GOSSIP:
					{
						if( Creature* announcer = instance->GetCreature(NPC_AnnouncerGUID) )
							announcer->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
						events.PopEvent();
					}
					break;
				case EVENT_START_ARGENT_CHALLENGE_INTRO:
					{
						if( Creature* announcer = instance->GetCreature(NPC_AnnouncerGUID) )
						{
							if( GameObject* gate = instance->GetGameObject(GO_MainGateGUID) )
							{
								announcer->SetFacingToObject(gate);
								HandleGameObject(GO_MainGateGUID, true, gate);
							}
							if( Counter )
							{
								announcer->AI()->Talk(TEXT_CHEER_EADRIC_1);
								announcer->AI()->Talk(TEXT_CHEER_EADRIC_2);
							}
							else
							{
								announcer->AI()->Talk(TEXT_CHEER_PALETRESS_1);
								announcer->AI()->Talk(TEXT_CHEER_PALETRESS_2);
							}
						}
							
						for( int8 i = 0; i < 3; ++i )
						{
							Position pos(SpawnPosition);
							float x = pos.GetPositionX();

							pos.m_positionX = x-2.0f+(i-1)*10.0f;
							if( Creature* pTrash = instance->SummonCreature(NPC_ARGENT_LIGHTWIELDER, pos) )
							{
								pTrash->AI()->SetData(i,0);
								NPC_ArgentSoldierGUID[i][0] = pTrash->GetGUID();
							}
							pos.m_positionX = x+(i-1)*10.0f;
							if( Creature* pTrash = instance->SummonCreature(NPC_ARGENT_MONK, pos) )
							{
								pTrash->AI()->SetData(i,0);
								NPC_ArgentSoldierGUID[i][1] = pTrash->GetGUID();
							}
							pos.m_positionX = x+2.0f+(i-1)*10.0f;
							if( Creature* pTrash = instance->SummonCreature(NPC_PRIESTESS, pos) )
							{
								pTrash->AI()->SetData(i,0);
								NPC_ArgentSoldierGUID[i][2] = pTrash->GetGUID();
							}
						}
						events.ScheduleEvent(EVENT_SUMMON_ARGENT_CHALLENGE, 4000);
						events.PopEvent();
					}
					break;
				case EVENT_SUMMON_ARGENT_CHALLENGE:
					{
						if( Creature* announcer = instance->GetCreature(NPC_AnnouncerGUID) )
							announcer->GetMotionMaster()->MovePoint(0, 735.81f, 661.92f, 412.39f);
						if( Creature* boss = instance->SummonCreature(Counter ? NPC_EADRIC : NPC_PALETRESS, SpawnPosition) )
							boss->GetMotionMaster()->MovePoint(0, 746.881f, 660.263f, 411.7f);
						events.ScheduleEvent(EVENT_CLOSE_GATE, 5000);
						events.ScheduleEvent(EVENT_ARGENT_CHALLENGE_SAY_1, 4000);
						events.ScheduleEvent(EVENT_ARGENT_SOLDIER_GROUP_ATTACK, 12500);
						events.PopEvent();
					}
					break;
				case EVENT_ARGENT_CHALLENGE_SAY_1:
					{
						if( Creature* ac = instance->GetCreature(NPC_ArgentChampionGUID) )
							ac->AI()->Talk(Counter ? TEXT_EADRIC_SAY_1 : TEXT_PALETRESS_SAY_1);
						if( !Counter )
							events.ScheduleEvent(EVENT_ARGENT_CHALLENGE_SAY_2, 6000);
						events.PopEvent();
					}
					break;
				case EVENT_ARGENT_CHALLENGE_SAY_2:
					{
						if( Creature* ac = instance->GetCreature(NPC_ArgentChampionGUID) )
							ac->AI()->Talk(TEXT_PALETRESS_SAY_2);
						events.PopEvent();
					}
					break;
				case EVENT_ARGENT_SOLDIER_GROUP_ATTACK:
					{
						Counter = 0;
						for( uint8 i=0; i<3; ++i )
							for( uint8 j=0; j<3; ++j )
								if( Creature* c = instance->GetCreature(NPC_ArgentSoldierGUID[i][j]) )
								{
									c->SetReactState(REACT_AGGRESSIVE);
									c->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
									//c->AI()->DoZoneInCombat();
								}
						if( Creature* tirion = instance->GetCreature(NPC_TirionGUID) )
							tirion->AI()->Talk(TEXT_YOU_MAY_BEGIN);
						events.PopEvent();
					}
					break;
				case EVENT_ARGENT_CHALLENGE_MOVE_FORWARD:
					{
						if( Creature* boss = instance->GetCreature(NPC_ArgentChampionGUID) )
							boss->GetMotionMaster()->MovePoint(0, 746.881f, 635.263f, 411.7f);
						events.ScheduleEvent(EVENT_ARGENT_CHALLENGE_ATTACK, 3000);
						events.PopEvent();
					}
					break;
				case EVENT_ARGENT_CHALLENGE_ATTACK:
					{
						if( Creature* boss = instance->GetCreature(NPC_ArgentChampionGUID) )
						{
							boss->SetReactState(REACT_AGGRESSIVE);
							boss->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
							if( Unit* target = boss->SelectNearestTarget(200.0f) )
								boss->AI()->AttackStart(target);
							boss->AI()->DoZoneInCombat();
						}
						events.PopEvent();
					}
					break;
				case EVENT_ARGENT_CHALLENGE_RUN_MIDDLE:
					{
						if( Creature* boss = instance->GetCreature(NPC_ArgentChampionGUID) )
						{
							boss->GetMotionMaster()->MovePoint(1, 747.13f, 628.037f, 411.2f);
							events.ScheduleEvent(EVENT_ARGENT_CHALLENGE_LEAVE_CHEST, 6000);
						}
						events.PopEvent();
					}
					break;
				case EVENT_ARGENT_CHALLENGE_LEAVE_CHEST:
					{
						if( Creature* announcer = instance->GetCreature(NPC_AnnouncerGUID) )
							if( Creature* boss = instance->GetCreature(NPC_ArgentChampionGUID) )
							{
								announcer->GetMotionMaster()->MovePoint(0, 743.14f, 628.77f, 411.2f);
								uint32 chest = 0;
								if( instance->IsHeroic() )
									chest = (boss->GetEntry() == NPC_EADRIC || boss->GetEntry() == NPC_EADRIC_H) ? GO_EADRIC_LOOT_H : GO_PALETRESS_LOOT_H;
								else
									chest = (boss->GetEntry() == NPC_EADRIC || boss->GetEntry() == NPC_EADRIC_H) ? GO_EADRIC_LOOT : GO_PALETRESS_LOOT;
								announcer->SummonGameObject(chest, 746.59f, 618.49f, 411.09f, 1.42f, 0, 0, 0, 0, 90000000); // [LOOT]
							}

						events.ScheduleEvent(EVENT_ARGENT_CHALLENGE_DISAPPEAR, 4000);
						events.ScheduleEvent(EVENT_RESTORE_ANNOUNCER_GOSSIP, 15000);
						events.PopEvent();
					}
					break;
				case EVENT_ARGENT_CHALLENGE_DISAPPEAR:
					{
						if( Creature* boss = instance->GetCreature(NPC_ArgentChampionGUID) )
						{
							boss->GetMotionMaster()->MovePoint(0, SpawnPosition);
							boss->DespawnOrUnsummon(3000);
						}
						events.PopEvent();
					}
					break;
				case EVENT_SUMMON_BLACK_KNIGHT:
					{
						if( Creature* announcer = instance->GetCreature(NPC_AnnouncerGUID) )
							if( Creature* bk_vehicle = announcer->SummonCreature(VEHICLE_BLACK_KNIGHT, 769.834f, 651.915f, 447.035f, 0.0f) )
							{
								NPC_BlackKnightVehicleGUID = bk_vehicle->GetGUID();
								bk_vehicle->SetReactState(REACT_PASSIVE);
								bk_vehicle->SetFacingTo(M_PI);
								if( Vehicle* v = bk_vehicle->GetVehicleKit() )
									if( Unit* bk = v->GetPassenger(0) )
									{
										NPC_BlackKnightGUID = bk->GetGUID();
										bk->SendMovementFlagUpdate(); // put him on vehicle visually
										if( bk->GetTypeId() == TYPEID_UNIT )
											bk->ToCreature()->SetReactState(REACT_PASSIVE);
									}

									announcer->SetFacingToObject(bk_vehicle);
									announcer->AI()->Talk(TEXT_BK_RAFTERS);
							}
						events.PopEvent();
					}
					break;
				case EVENT_START_BLACK_KNIGHT_SCENE:
					{
						if( Creature* bk = instance->GetCreature(NPC_BlackKnightGUID) )
						{
							Position exitPos = {745.016f, 631.506f, 411.575f, M_PI};
							bk->ExitVehicle(/*&exitPos*/);
							bk->GetMotionMaster()->MoveJump(exitPos, 2.0f, 2.0f);
							bk->AI()->Talk(TEXT_BK_SPOILED);
						}
						events.ScheduleEvent(EVENT_BLACK_KNIGHT_CAST_ANNOUNCER, 2000);
						events.PopEvent();
					}
					break;
				case EVENT_BLACK_KNIGHT_CAST_ANNOUNCER:
					{
						if( Creature* announcer = instance->GetCreature(NPC_AnnouncerGUID) )
						{
							if( Creature* bk = instance->GetCreature(NPC_BlackKnightGUID) )
							{
								bk->SetPosition(745.016f, 631.506f, 411.575f, bk->GetAngle(announcer));
								bk->SetHomePosition(*bk);
								bk->SetFacingToObject(announcer);
								announcer->SetFacingToObject(bk);
								announcer->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
								bk->AddAura(68306, announcer); // spell has attribute player only
								if( Creature* tirion = instance->GetCreature(NPC_TirionGUID) )
									tirion->AI()->Talk(TEXT_BK_MEANING);
							}
						}
						events.ScheduleEvent(EVENT_BLACK_KNIGHT_KILL_ANNOUNCER, 1000);
						events.PopEvent();
					}
					break;
				case EVENT_BLACK_KNIGHT_KILL_ANNOUNCER:
					{
						if( Creature* bk_vehicle = instance->GetCreature(NPC_BlackKnightVehicleGUID) )
							bk_vehicle->AI()->DoAction(1);

						events.ScheduleEvent(EVENT_BLACK_KNIGHT_MOVE_FORWARD, 4000);
						events.PopEvent();
					}
					break;
				case EVENT_BLACK_KNIGHT_MOVE_FORWARD:
					{
						if( Creature* bk = instance->GetCreature(NPC_BlackKnightGUID) )
						{
							bk->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
							bk->GetMotionMaster()->MovePoint(0, 746.81f, 623.15f, 411.42f);
							bk->AI()->Talk(TEXT_BK_LICH);
						}
						if( Creature* announcer = instance->GetCreature(NPC_AnnouncerGUID) )
							if (announcer->IsAlive())
								Unit::Kill(announcer, announcer);
						events.ScheduleEvent(EVENT_BLACK_KNIGHT_SAY_TASK, 14000);
						events.PopEvent();
					}
					break;
				case EVENT_BLACK_KNIGHT_SAY_TASK:
					{
						if( Creature* bk = instance->GetCreature(NPC_BlackKnightGUID) )
						{
							bk->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
							bk->AI()->Talk(TEXT_BK_TASK);
						}
						events.ScheduleEvent(EVENT_BLACK_KNIGHT_ATTACK, 5000);
						events.PopEvent();
					}
					break;
				case EVENT_BLACK_KNIGHT_ATTACK:
					{
						if( Creature* bk = instance->GetCreature(NPC_BlackKnightGUID) )
						{
							bk->SetReactState(REACT_AGGRESSIVE);
							bk->SetUInt32Value(UNIT_FIELD_FLAGS, 0);
							if( Unit* target = bk->SelectNearestTarget(200.0f) )
								bk->AI()->AttackStart(target);
							bk->AI()->DoZoneInCombat();
							bk->AI()->DoAction(1);
						}
						events.PopEvent();
					}
					break;
			}			
		}

		bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* target = NULL, uint32 miscvalue1 = 0)
		{
			switch(criteria_id)
			{
				case 11789: // I've Had Worse criteria id
					return bAchievIveHadWorse;
				case 11863:
					return NPC_MemoryEntry == 34942;
				case 11904:
					return NPC_MemoryEntry == 35028;
				case 11905:
					return NPC_MemoryEntry == 35029;
				case 11906:
					return NPC_MemoryEntry == 35030;
				case 11907:
					return NPC_MemoryEntry == 35031;
				case 11908:
					return NPC_MemoryEntry == 35032;
				case 11909:
					return NPC_MemoryEntry == 35033;
				case 11910:
					return NPC_MemoryEntry == 35034;
				case 11911:
					return NPC_MemoryEntry == 35036;
				case 11912:
					return NPC_MemoryEntry == 35037;
				case 11913:
					return NPC_MemoryEntry == 35038;
				case 11914:
					return NPC_MemoryEntry == 35039;
				case 11915:
					return NPC_MemoryEntry == 35040;
				case 11916:
					return NPC_MemoryEntry == 35041;
				case 11917:
					return NPC_MemoryEntry == 35042;
				case 11918:
					return NPC_MemoryEntry == 35043;
				case 11919:
					return NPC_MemoryEntry == 35044;
				case 11920:
					return NPC_MemoryEntry == 35045;
				case 11921:
					return NPC_MemoryEntry == 35046;
				case 11922:
					return NPC_MemoryEntry == 35047;
				case 11923:
					return NPC_MemoryEntry == 35048;
				case 11924:
					return NPC_MemoryEntry == 35049;
				case 11925:
					return NPC_MemoryEntry == 35050;
				case 11926:
					return NPC_MemoryEntry == 35051;
				case 11927:
					return NPC_MemoryEntry == 35052;
			}
			return false;
		}
	};
};

void AddSC_instance_trial_of_the_champion()
{
	new instance_trial_of_the_champion();
}
